﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Linq;
using IkeCode.WP7.HQReader.Interfaces;
using IkeCode.WP7.HQReader.Base;
using IkeCode.WP7.Toolkit;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel.Syndication;
using Newtonsoft.Json;
using IkeCode.WP7.Toolkit.Persist;
using System.Windows.Media.Imaging;

namespace IkeCode.WP7.HQReader.Model
{
    /// <summary>
    /// Model for Feeds, implements IIcFeed
    /// </summary>
    /// <see cref="IkeCode.WP7.HQReader.Interfaces.IIcFeed"/>
    [JsonObject(MemberSerialization.OptIn)]
    public sealed class IcFeedModel : IcBaseModel, IIcFeed, IIcFeedActions
    {
        #region Properties

        /// <summary>
        /// Syndication Feed
        /// </summary>
        public SyndicationFeed SyndicationFeed { get; private set; }

        #endregion Properties

        #region Fields

        Uri _url;
        Uri _imageUrl;
        List<string> _categories;
        int _commentsCount;
        string _publisherName;

        #endregion Fields

        #region Interface Fields

        /// <summary>
        /// Feed Url (on web)
        /// </summary>
        [JsonProperty(PropertyName = "Url")]
        public Uri Url
        {
            get { return this._url; }
            set { this._url = value; }
        }

        /// <summary>
        /// Image of post
        /// </summary>
        [JsonProperty(PropertyName = "ImageUrl")]
        [CacheImage()]
        public Uri ImageUrl
        {
            get { return this._imageUrl; }
            set { this._imageUrl = value; }
        }

        /// <summary>
        /// Feed item categories
        /// </summary>
        [JsonProperty(PropertyName = "Categories")]
        public List<string> Categories
        {
            get { return this._categories; }
            set { this._categories = value; }
        }

        /// <summary>
        /// Number of comments in post
        /// </summary>
        [JsonProperty(PropertyName = "CommentsCount")]
        public int CommentsCount
        {
            get { return this._commentsCount; }
            set { this._commentsCount = value; }
        }

        /// <summary>
        /// Publisher Name
        /// </summary>
        [JsonProperty(PropertyName = "PublisherName")]
        public string PublisherName
        {
            get { return string.IsNullOrWhiteSpace(this._publisherName) ? "" : this._publisherName.Length > 37 ? this._publisherName.Substring(0, 37) + "..." : this._publisherName; }
            set { this._publisherName = value; }
        }

        #endregion Interface Fields

        #region Constructors

        /// <summary>
        /// Used just for design bindings
        /// </summary>
        public IcFeedModel() { }

        /// <summary>
        /// Used to use GetList method.
        /// </summary>
        /// <param name="syndFeed">Syndication Feed object</param>
        public IcFeedModel(SyndicationFeed syndFeed)
        {
            this.SyndicationFeed = syndFeed;
        }

        /// <summary>
        /// Used to bind GetList item objects
        /// </summary>
        /// <param name="syndItem">Syndication Item object</param>
        public IcFeedModel(SyndicationItem syndItem)
        {
            this.Id = Guid.NewGuid();
            this._url = new Uri(syndItem.Id, UriKind.Absolute);
            this.Title = syndItem.Title.Text;
            this.InsertDate = syndItem.PublishDate.TryParse();
            this.UniqueId = MD5Core.GetHashString(string.Format("{0}{1}", this.Title, this.InsertDate));
            this.ImageUrl = syndItem.TryGetImageUrl();
            //this._description = description;
            //this._commentsCount = commentsCount;
            //this._publisherName = publisherName;
        }

        /// <summary>
        /// Constructor with manual properties binding, usually used for design data services
        /// </summary>
        /// <param name="id">Feed Id</param>
        /// <param name="url">Feed Url</param>
        /// <param name="title">Feed Title</param>
        /// <param name="dateIns">Feed Publication Date</param>
        /// <param name="imageUrl">Feed Image Url</param>
        /// <param name="categories">Feed Categories</param>
        /// <param name="commentsCount">Feed Comments Count</param>
        /// <param name="publisherName">Feed Publisher</param>
        public IcFeedModel(Guid id, string url, string title, DateTime dateIns, string imageUrl, List<string> categories, int commentsCount, string publisherName)
            : this()
        {
            this.Id = id == Guid.Empty ? Guid.NewGuid() : id;
            this.Url = new Uri(url, UriKind.Absolute);
            this.Title = title;
            this.InsertDate = dateIns;
            this.UniqueId = MD5Core.GetHashString(string.Format("{0}{1}", this.Title, this.InsertDate));
            this.ImageUrl = new Uri(imageUrl);
            this.Categories = categories;
            this.CommentsCount = commentsCount;
            this.PublisherName = publisherName;
        }

        #endregion Constructors

        /// <summary>
        /// Try to get feed items
        /// </summary>
        /// <returns>List of <see cref="IkeCode.WP7.HQReader.Interfaces.IIcFeed">IIcFeed</see></returns>
        public List<IIcFeed> GetList()
        {
            var result = new List<IIcFeed>();

            if (this.SyndicationFeed != null && this.SyndicationFeed.Items != null && this.SyndicationFeed.Items.Count() > 0)
            {
                foreach (var item in this.SyndicationFeed.Items)
                {
                    //Won't able to stream videos yet
                    if (!string.IsNullOrWhiteSpace(item.Summary.Text.TryGetYoutubeUrl()))
                        continue;

                    var model = new IcFeedModel(item);
                    result.Add(model);
                }
            }

            return result;
        }
    }
}
